
package com.lzb.play.utils;

import android.os.Handler;
import android.os.Looper;

import androidx.annotation.NonNull;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * OkHttp POST请求工具类
 * 支持普通表单、JSON、文件上传等多种请求方式
 */
public class OkHttpPostUtil {

    private static final String TAG = "OkHttpPostUtil";
    private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
    private static final MediaType FORM = MediaType.get("application/x-www-form-urlencoded; charset=utf-8");
    private static final MediaType MULTIPART = MediaType.get("multipart/form-data");

    private static OkHttpPostUtil instance;
    private final OkHttpClient client;
    private final Handler mainHandler;

    // 请求超时时间（秒）
    private static final int CONNECT_TIMEOUT = 30;
    private static final int READ_TIMEOUT = 30;
    private static final int WRITE_TIMEOUT = 30;

    private OkHttpPostUtil() {
        mainHandler = new Handler(Looper.getMainLooper());
        client = new OkHttpClient.Builder()
                .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
                .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
                .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
                .build();
    }

    public static OkHttpPostUtil getInstance() {
        if (instance == null) {
            synchronized (OkHttpPostUtil.class) {
                if (instance == null) {
                    instance = new OkHttpPostUtil();
                }
            }
        }
        return instance;
    }

    /**
     * 发送POST表单请求
     */
    public void postForm(String url, Map<String, String> params, HttpCallback callback) {
        FormBody.Builder formBuilder = new FormBody.Builder();
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                formBuilder.add(entry.getKey(), entry.getValue());
            }
        }

        RequestBody requestBody = formBuilder.build();
        sendRequest(url, requestBody, callback);
    }

    /**
     * 发送POST JSON请求
     */
    public void postJson(String url, JSONObject jsonObject, HttpCallback callback) {
        RequestBody requestBody = RequestBody.create(jsonObject.toString(), JSON);
        sendRequest(url, requestBody, callback);
    }

    /**
     * 发送POST JSON请求（Map参数）
     */
    public void postJson(String url, Map<String, Object> params, HttpCallback callback) {
        JSONObject jsonObject = new JSONObject(params);
        postJson(url, jsonObject, callback);
    }

    /**
     * 发送POST JSON请求（String参数）
     */
    public void postJson(String url, String jsonString, HttpCallback callback) {
        try {
            JSONObject jsonObject = new JSONObject(jsonString);
            postJson(url, jsonObject, callback);
        } catch (JSONException e) {
            if (callback != null) {
                callback.onFailure("JSON格式错误: " + e.getMessage());
            }
        }
    }

    /**
     * 文件上传（单文件）
     */
    public void uploadFile(String url, String fileKey, File file, Map<String, String> params, HttpCallback callback) {
        MultipartBody.Builder multipartBuilder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM);

        // 添加表单参数
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                multipartBuilder.addFormDataPart(entry.getKey(), entry.getValue());
            }
        }

        // 添加文件
        if (file != null && file.exists()) {
            RequestBody fileBody = RequestBody.create(file, MediaType.parse("application/octet-stream"));
            multipartBuilder.addFormDataPart(fileKey, file.getName(), fileBody);
        }

        RequestBody requestBody = multipartBuilder.build();
        sendRequest(url, requestBody, callback);
    }

    /**
     * 文件上传（多文件）
     */
    public void uploadFiles(String url, Map<String, File> files, Map<String, String> params, HttpCallback callback) {
        MultipartBody.Builder multipartBuilder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM);

        // 添加表单参数
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                multipartBuilder.addFormDataPart(entry.getKey(), entry.getValue());
            }
        }

        // 添加文件
        if (files != null) {
            for (Map.Entry<String, File> entry : files.entrySet()) {
                File file = entry.getValue();
                if (file != null && file.exists()) {
                    RequestBody fileBody = RequestBody.create(file, MediaType.parse("application/octet-stream"));
                    multipartBuilder.addFormDataPart(entry.getKey(), file.getName(), fileBody);
                }
            }
        }

        RequestBody requestBody = multipartBuilder.build();
        sendRequest(url, requestBody, callback);
    }

    /**
     * 发送请求（内部方法）
     */
    private void sendRequest(String url, RequestBody requestBody, HttpCallback callback) {
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                postToMainThread(() -> {
                    if (callback != null) {
                        callback.onFailure("网络错误: " + e.getMessage());
                    }
                });
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                try {
                    final String responseBody = response.body() != null ? response.body().string() : "";
                    postToMainThread(() -> {
                        if (callback != null) {
                            if (response.isSuccessful()) {
                                callback.onSuccess(responseBody);
                            } else {
                                callback.onFailure("请求失败: " + response.code() + " - " + response.message());
                            }
                        }
                    });
                } catch (Exception e) {
                    postToMainThread(() -> {
                        if (callback != null) {
                            callback.onFailure("响应解析错误: " + e.getMessage());
                        }
                    });
                } finally {
                    if (response.body() != null) {
                        response.body().close();
                    }
                }
            }
        });
    }

    /**
     * 在主线程中执行回调
     */
    private void postToMainThread(Runnable runnable) {
        mainHandler.post(runnable);
    }

    /**
     * 取消所有请求
     */
    public void cancelAllRequests() {
        client.dispatcher().cancelAll();
    }

    /**
     * 取消指定tag的请求
     */
    public void cancelRequest(String tag) {
        for (Call call : client.dispatcher().queuedCalls()) {
            if (tag.equals(call.request().tag())) {
                call.cancel();
            }
        }
        for (Call call : client.dispatcher().runningCalls()) {
            if (tag.equals(call.request().tag())) {
                call.cancel();
            }
        }
    }

    /**
     * 设置请求超时时间
     */
    public void setTimeout(int connectTimeout, int readTimeout, int writeTimeout) {
        OkHttpClient newClient = client.newBuilder()
                .connectTimeout(connectTimeout, TimeUnit.SECONDS)
                .readTimeout(readTimeout, TimeUnit.SECONDS)
                .writeTimeout(writeTimeout, TimeUnit.SECONDS)
                .build();
        // 注意：这里需要重新创建实例，OkHttpClient是不可变的
    }

    /**
     * HTTP请求回调接口
     */
    public interface HttpCallback {
        void onSuccess(String response);
        void onFailure(String error);
    }

    /**
     * 同步请求（阻塞调用，需在子线程中使用）
     */
    public String postSync(String url, Map<String, String> params) throws IOException {
        FormBody.Builder formBuilder = new FormBody.Builder();
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                formBuilder.add(entry.getKey(), entry.getValue());
            }
        }

        Request request = new Request.Builder()
                .url(url)
                .post(formBuilder.build())
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful() && response.body() != null) {
                return response.body().string();
            } else {
                throw new IOException("请求失败: " + response.code());
            }
        }
    }
}